package cn.taketoday.live.controller;

import com.alibaba.fastjson.JSONObject;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import cn.taketoday.live.Json;
import cn.taketoday.live.config.CenterSetConfig;
import cn.taketoday.live.config.GlobalData;
import cn.taketoday.live.config.settings.AdvertSetConf;
import cn.taketoday.live.config.settings.AutoReplySetConf;
import cn.taketoday.live.config.settings.ThankFollowSetConf;
import cn.taketoday.live.config.settings.ThankGiftSetConf;
import cn.taketoday.live.config.settings.ThankWelcomeSetConf;
import cn.taketoday.live.data.LoginData;
import cn.taketoday.live.data.Qrcode;
import cn.taketoday.live.data.room.RoomBlock;
import cn.taketoday.live.http.BilibiliHttpRequests;
import cn.taketoday.live.http.HttpOtherData;
import cn.taketoday.live.http.HttpRoomData;
import cn.taketoday.live.service.ClientService;
import cn.taketoday.live.service.SettingsService;
import cn.taketoday.live.utils.FileUtils;
import cn.taketoday.live.utils.ObjectUtils;
import cn.taketoday.live.utils.QrcodeUtils;

/**
 * @author BanqiJane
 * @ClassName WebController
 * @Description TODO
 * @date 2020年8月10日 下午12:21:50
 * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved.
 */
@Controller
@Deprecated
public class WebController {
  private SettingsService checkService;
  private ClientService clientService;

  @RequestMapping(value = { "/", "index" })
  public String index(HttpServletRequest req, Model model) {
    if (!StringUtils.isEmpty(GlobalData.USERCOOKIE)) {
      final HttpSession httpSession = req.getSession();
      if (httpSession.getAttribute("status") == null) {
        httpSession.setAttribute("status", "login");
      }
    }

    model.addAttribute("ANAME", GlobalData.ANCHOR_NAME);
    model.addAttribute("EDITION", GlobalData.EDITION);
    model.addAttribute("ROOMID", GlobalData.ROOM_ID);
    model.addAttribute("POPU", GlobalData.ROOM_POPULARITY);
    model.addAttribute("MANAGER", GlobalData.USERMANAGER != null ? GlobalData.USERMANAGER.isIs_manager() : false);

    if (GlobalData.USER != null) {
      model.addAttribute("USER", GlobalData.USER);
    }

    return "index";
  }

  @RequestMapping(value = "/connect")
  public String connect(Model model) {
    model.addAttribute("ROOMID", GlobalData.centerSetConf.getRoomid());
    return "connect";
  }

  @RequestMapping(value = "/login")
  public String login(HttpServletRequest req) {
    if (req.getSession().getAttribute("status") == null) {
      return "login";
    }
    else {
      return "redirect:/";
    }

  }

  @RequestMapping(value = "/quit")
  public String quit(HttpServletRequest req) {
    req.getSession().setAttribute("status", null);
    req.getSession().removeAttribute("status");
    if (!StringUtils.isEmpty(GlobalData.USERCOOKIE)) {
      BilibiliHttpRequests.quit();
      checkService.quit();
    }
    return "login";
  }

  @ResponseBody
  @RequestMapping(value = "/qrcode", method = RequestMethod.GET)
  public void qrcode(HttpServletRequest req, HttpServletResponse resp, @RequestParam("url") String url) throws Exception {
    if (req.getSession().getAttribute("status") != null)
      return;
    QrcodeUtils.creatRrCode(url, 140, 140, resp);
  }

  @ResponseBody
  @RequestMapping(value = "/qrcodeUrl", method = RequestMethod.POST)
  public Json qrcodeUrl(HttpServletRequest req) {
    if (req.getSession().getAttribute("status") != null)
      return null;
    Qrcode qrcode = BilibiliHttpRequests.getQrcode();
    req.getSession().setAttribute("auth", qrcode.getOauthKey());
    return Json.ok((Object)qrcode.getUrl());
  }

  @ResponseBody
  @RequestMapping(value = "/loginCheck", method = RequestMethod.POST)
  public JSONObject loginCheck(HttpServletRequest req) {
    if (req.getSession().getAttribute("status") != null)
      return null;
    JSONObject jsonObject = null;
    String oauthKey = (String) req.getSession().getAttribute("auth");
    LoginData loginData = new LoginData();
    loginData.setOauthKey(oauthKey);
    String jsonString = BilibiliHttpRequests.getCookie(loginData);
    jsonObject = JSONObject.parseObject(jsonString);
    if (jsonObject != null) {
      if (jsonObject.getBoolean("status")) {
        checkService.init(1);
        if (GlobalData.USER != null) {
          req.getSession().setAttribute("status", "login");
        }
      }
    }
    return jsonObject;
  }

  @ResponseBody
  @RequestMapping(value = "/connectRoom", method = RequestMethod.GET)
  public Json connectRoom(@RequestParam("roomid") Long roomid) {
    boolean flag = false;
    if (null == GlobalData.webSocketProxy || !GlobalData.webSocketProxy.isOpen()) {
      try {
        clientService.startConnService(roomid);
      }
      catch (Exception e) {
        // TODO 自动生成的 catch 块
        e.printStackTrace();
      }
      if (GlobalData.ROOM_ID != null) {
        GlobalData.centerSetConf.setRoomid(GlobalData.ROOM_ID);
        GlobalData.ROOMID_SAFE = GlobalData.ROOM_ID;
      }
      checkService.connectSet(GlobalData.centerSetConf);
    }
    if (GlobalData.webSocketProxy != null) {
      if (GlobalData.webSocketProxy.isOpen()) {
        flag = true;
      }
    }
    return Json.ok(flag);
  }

  @ResponseBody
  @RequestMapping(value = "/disconnectRoom", method = RequestMethod.GET)
  public Json disconnectRoom() {
    boolean flag = false;
    flag = clientService.closeConnService();
    return Json.ok(flag);
  }

  @ResponseBody
  @RequestMapping(value = "/connectCheck", method = RequestMethod.GET)
  public Json connectCheck() {
    boolean flag = false;
    if (GlobalData.webSocketProxy != null) {
      if (GlobalData.webSocketProxy.isOpen()) {
        flag = true;
      }
    }
    return Json.ok(flag);
  }

  @ResponseBody
  @RequestMapping(value = "/heartBeat", method = RequestMethod.GET)
  public Json heartBeat() {
    return Json.ok(GlobalData.ROOM_POPULARITY);
  }

  @ResponseBody
  @RequestMapping(value = "/getSet", method = RequestMethod.GET)
  public Json getSet() {
    return Json.ok(GlobalData.centerSetConf);
  }

  @ResponseBody
  @RequestMapping(value = "/sendSet", method = RequestMethod.POST)
  public Json sendSet(@RequestParam("set") String set) {
    try {
      CenterSetConfig centerSetConf = JSONObject.parseObject(set, CenterSetConfig.class);
      checkService.update(centerSetConf);

    }
    catch (Exception e) {
      // TODO: handle exception
      return Json.ok(false);
    }
    return Json.ok(true);
  }

  @ResponseBody
  @RequestMapping(value = "/getIp", method = RequestMethod.GET)
  public Json getIp() {
    String ip = HttpOtherData.httpGetIp();
    if (!StringUtils.isEmpty(ip)) {
      return Json.ok(ip);
    }
    else {
      return Json.ok(null);
    }

  }

  @ResponseBody
  @GetMapping("/checkupdate")
  public Json checkUpdate() {
    return Json.ok(1);
  }

  @ResponseBody
  @RequestMapping(value = "/block", method = RequestMethod.GET)
  public Json block(@RequestParam("uid") long uid, @RequestParam("time") short time) {
    short code = -1;
    if (time > 720 && time <= 0) {
      //required time error
      code = 2;
      return Json.ok(code);
    }
    if (StringUtils.isNotBlank(GlobalData.USERCOOKIE)) {
      code = BilibiliHttpRequests.addBlock(uid, time);
    }
    return Json.ok(code);
  }

  @ResponseBody
  @RequestMapping(value = "/del_block", method = RequestMethod.GET)
  public Json del_block(@RequestParam("id") long id) {
    short code = -1;
    code = BilibiliHttpRequests.deleteBlock(id);
    return Json.ok(code);
  }

  @ResponseBody
  @RequestMapping(value = "/blocks", method = RequestMethod.GET)
  public Json blocks(@RequestParam("page") int page) {
    if (page <= 0) {
      page = 1;
    }
    List<RoomBlock> roomBlockList = new ArrayList<>();
    if (GlobalData.ROOM_ID != null && StringUtils
            .isNotBlank(GlobalData.USERCOOKIE) && GlobalData.USERMANAGER != null && GlobalData.USERMANAGER.isIs_manager()) {
      roomBlockList = HttpRoomData.getBlockList(page);
    }
    return Json.ok(roomBlockList);
  }

  @ResponseBody
  @RequestMapping(value = "/setExport", method = RequestMethod.GET)
  public Json setExport() throws IOException {
    boolean flag = FileUtils.createJsonFile(GlobalData.centerSetConf.toJson());
    if (flag) {
      return Json.ok(0);
    }
    else {
      return Json.ok(1);
    }
  }

  @ResponseBody
  @RequestMapping(value = "/setImport", method = RequestMethod.POST)
  public Json setImport(@RequestParam("file") MultipartFile file) throws IOException {
    if (!file.getResource().getFilename().endsWith(".json")) {
      return Json.ok(2);
    }
    String jsonString = new BufferedReader(new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8))
            .lines().collect(Collectors.joining(System.lineSeparator()));
    try {

      CenterSetConfig centerSetConf = ObjectUtils.fromJSON(jsonString, CenterSetConfig.class);
      if (centerSetConf != null) {
        if (centerSetConf.getAdvert() == null) {
          centerSetConf.setAdvert(new AdvertSetConf());
        }
        if (centerSetConf.getFollow() == null) {
          centerSetConf.setFollow(new ThankFollowSetConf());
        }
        if (centerSetConf.getThank_gift() == null) {
          centerSetConf.setThank_gift(new ThankGiftSetConf());
        }
        if (centerSetConf.getReply() == null) {
          centerSetConf.setReply(new AutoReplySetConf());
        }
        if (centerSetConf.getWelcome() == null) {
          centerSetConf.setWelcome(new ThankWelcomeSetConf());
        }
        centerSetConf.setClock_in(GlobalData.centerSetConf.getClock_in());
        BeanUtils.copyProperties(centerSetConf, GlobalData.centerSetConf);
        checkService.update(centerSetConf);
      }
    }
    catch (Exception e) {
      return Json.ok(1);
    }
    return Json.ok(0);
  }

  @Autowired
  public void setCheckService(SettingsService checkService) {
    this.checkService = checkService;
  }

  @Autowired
  public void setClientService(ClientService clientService) {
    this.clientService = clientService;
  }
}
